﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;

namespace Notoric.View.Music.CWNotation.Controls
{
    /// <summary>
    /// Visualizes a chord.
    /// </summary>
    public partial class Chord : UserControl
    {
        #region Constructors

        /// <summary>
        /// Creates a new <see cref="Chord"/> instance.
        /// </summary>
        public Chord()
        {
            InitializeComponent();
        }

        #endregion

        #region Event Handlers

        /// <summary>
        /// Handles the DataContextChanged event of the UserControl control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
        private void UserControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (chord != null)
                chord.PropertyChanged -= chord_PropertyChanged;

            chord = DataContext as ViewModel.Elements.CWNotation.Chord;

            if (chord != null)
                chord.PropertyChanged += new PropertyChangedEventHandler(chord_PropertyChanged);

            SetVisualization();
        }

        /// <summary>
        /// Handles the PropertyChanged event of the vizualized chord.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.ComponentModel.PropertyChangedEventArgs"/> instance containing the event data.</param>
        private void chord_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "ArticulationPosition" || e.PropertyName == "Articulation")
                SetVisualization();
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Sets the visualization.
        /// </summary>
        private void SetVisualization()
        {
            if (chord == null || chord.Notes.Count == 0)
            {
                PART_ArticulationSymbol.Text = "";
                return;
            }

            var staffSpaces = chord.FindOwner<ViewModel.Elements.CWNotation.Staff>().Lines.Count - 1;
            var spaceSize = (staffSpaces > 0 ? chord.EffectiveTypeSize / staffSpaces : chord.FindOwner<ViewModel.Elements.CWNotation.Staff>().SpaceSize);
            bool down = (chord.StemDirection == ViewModel.Elements.CWNotation.StemOrientation.Up && chord.ArticulationPosition < chord.Notes[0].VerticalPosition) ||
                (chord.StemDirection == ViewModel.Elements.CWNotation.StemOrientation.Down && chord.ArticulationPosition < chord.Notes[chord.Notes.Count - 1].VerticalPosition);

            switch (chord.Articulation)
            {
                case ViewModel.Elements.CWNotation.ArticulationType.Legato:
                    PART_ArticulationSymbol.Text = "";
                    break;
                case ViewModel.Elements.CWNotation.ArticulationType.Portamento:
                    if (down)
                        PART_ArticulationSymbol.Text = "";
                    else
                        PART_ArticulationSymbol.Text = "";
                    break;
                case ViewModel.Elements.CWNotation.ArticulationType.Staccatissimo:
                    if (down)
                    {
                        PART_ArticulationSymbol.Text = "®";
                        PART_ArticulationSymbol.Margin = new Thickness((chord.StemDirection == ViewModel.Elements.CWNotation.StemOrientation.Up ? -spaceSize / 2 : spaceSize / 2), -5.5 * spaceSize, 0, 0);
                    }
                    else
                    {
                        PART_ArticulationSymbol.Text = "'";
                        PART_ArticulationSymbol.Margin = new Thickness((chord.StemDirection == ViewModel.Elements.CWNotation.StemOrientation.Up ? -spaceSize / 2 : spaceSize / 2), -5 * spaceSize, 0, 0);
                    }
                    break;
                case ViewModel.Elements.CWNotation.ArticulationType.Staccato:
                    PART_ArticulationSymbol.Text = ".";
                    PART_ArticulationSymbol.Margin = new Thickness((chord.StemDirection == ViewModel.Elements.CWNotation.StemOrientation.Up ? -spaceSize / 2 : spaceSize / 2), -5.5 * spaceSize, 0, 0);
                    break;
                case ViewModel.Elements.CWNotation.ArticulationType.Tenuto:
                    PART_ArticulationSymbol.Text = "-";
                    PART_ArticulationSymbol.Margin = new Thickness((chord.StemDirection == ViewModel.Elements.CWNotation.StemOrientation.Up ? -spaceSize : 0), -5.5 * spaceSize, 0, 0);
                    break;
            }
        }

        #endregion

        #region Private Fields

        /// <summary>
        /// Holds a reference to the visualized chord.
        /// </summary>
        private ViewModel.Elements.CWNotation.Chord chord;

        #endregion
    }
}
